package retrospection.单词搜索;

/**
 * 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中，返回 true ；否则，返回 false 。
 * <p>
 * 单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
 */

public class Solution {
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (board[i][j] == word.charAt(0)) {
                    Boolean backtrack = backtrack(board, new boolean[m][n], word, m, n, 0, i, j);
                    if (backtrack) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    Boolean backtrack(char[][] board, boolean[][] used, String word, int m, int n, int index, int r, int c) {
        if (index == word.length()) {
            return true;
        }
        if (r < 0 || c < 0 || r >= m || c >= n) {
            return false;
        }
        if (used[r][c]) {
            return false;
        }
        if (board[r][c] != word.charAt(index)) {
            return false;
        }
        used[r][c] = true;
        Boolean right = backtrack(board, used, word, m, n, index + 1, r + 1, c);
        Boolean left = backtrack(board, used, word, m, n, index + 1, r - 1, c);
        Boolean down = backtrack(board, used, word, m, n, index + 1, r, c + 1);
        Boolean up = backtrack(board, used, word, m, n, index + 1, r, c - 1);
        used[r][c] = false;
        return right || left || down || up;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        solution.exist(new char[][]{{'a'}}, "a");
    }
}
